/**
 * ZHU framework. Copyright 2007-, all rights reserved.
 *
 * $Id: DateUtils.java 48 2013-05-08 05:47:27Z zhuxiaopeng $
 * $Revision: 48 $
 * $Date: 2013-05-08 13:47:27 +0800 (三, 2013-05-08) $
 * $Author: zhuxiaopeng $
 */
package daily.util;

import java.text.*;
import java.util.*;

/**
 * <p>
 * 日付に関連する便利メソッドを集めたユーティリティクラス。
 * </p>
 * <h3>スレッドセーフ性</h3>
 * <p>
 * このClassのインスタンスは不可変であるため、スレッドセーフである。
 * </p>
 * 
 * @author $Author: zhuxiaopeng $
 * @version $Revision: 48 $ - $Date: 2013-05-08 13:47:27 +0800 (三, 2013-05-08) $
 */
public class DateUtils {
	static final public Locale IMPERIAL_LOCALE = new Locale("ja", "JP", "JP");

	static public int compareIgnoreTime(final Date d, final Date e) {
		if (d == null || e == null) {
			throw new NullPointerException();
		}
		return removeTime(d).compareTo(removeTime(e));
	}

	static public int getYear(final Date date) {
		final Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.YEAR);
	}

	static public int getMonth(final Date date) {
		final Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.MONTH);
	}

	static public int getDayOfMonth(final Date date) {
		final Calendar caldate = getCalendar(date);
		return caldate.getActualMaximum(Calendar.DAY_OF_MONTH);
	}

	/**
	 * <p>
	 * 週の初めの日を取得する
	 * </p>
	 * 
	 * @param date
	 * @return
	 */
	static public Date getFirstDayOfWeek(final Date date) {
		final Calendar caldate = getCalendar(date);
		caldate.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
		return caldate.getTime();
	}

	/**
	 * <p>
	 * 週末を取得する
	 * </p>
	 * 
	 * @param date
	 * @return
	 */
	static public Date getLastDayOfWeek(final Date date) {
		final Calendar caldate = getCalendar(date);
		caldate.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
		return caldate.getTime();
	}

	/**
	 * <p>
	 * ついたちを取得する
	 * </p>
	 * 
	 * @param date
	 * @return
	 */
	static public Date getFirstDayOfMonth(final Date date) {
		final Calendar caldate = getCalendar(date);
		caldate.set(Calendar.DAY_OF_MONTH, 1);
		return caldate.getTime();
	}

	/**
	 * <p>
	 * 月末を取得する
	 * </p>
	 * 
	 * @param date
	 * @return
	 */
	static public Date getLastDayOfMonth(final Date date) {
		final Calendar caldate = getCalendar(date);
		caldate.set(Calendar.DAY_OF_MONTH, caldate.getActualMaximum(Calendar.DAY_OF_MONTH));
		return caldate.getTime();
	}

	/**
	 * <p>
	 * 月内の周を返す
	 * </p>
	 * 
	 * @param date
	 * @return
	 */
	static public int getDayOfWeekInMonth(final Date date) {
		final Calendar c = getCalendar(date);
		return c.get(Calendar.WEEK_OF_MONTH);
	}

	/**
	 * <p>
	 * 日付の加減算を行う
	 * </p>
	 * 
	 * @param date
	 * @param amount
	 * @return
	 */
	static public Date getCalculateDayDate(final Date date, final int amount) {
		if (date == null) {
			return null;
		}
		final Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.DATE, amount);
		return cal.getTime();
	}

	/**
	 * <p>
	 * 日付の加減算を行う
	 * </p>
	 * 
	 * @param date
	 * @param amount
	 * @return
	 */
	static public Date getCalculateMonthDate(final Date date, final int amount) {
		if (date == null) {
			return null;
		}
		final Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, amount);
		return cal.getTime();
	}

	/**
	 * <p>
	 * 年、月、日より日付を返す
	 * </p>
	 * 
	 * @param year
	 * @param month
	 * @param day
	 * @return
	 */
	static public Date getDate(final int year, final int month, final int day) {
		final Calendar calendar = Calendar.getInstance();
		calendar.clear();
		calendar.set(year, month, day);
		return calendar.getTime();
	}

	/**
	 * <p>
	 * 時間を消す
	 * </p>
	 * 
	 * @param date
	 * @return
	 */
	static public Date removeTime(final Date date) {
		return getCalendar(date).getTime();
	}

	/**
	 * <p>
	 * 和暦をフォマットする
	 * </p>
	 * 
	 * @param date
	 * @param pattern
	 * @return
	 */
	static public String dateToTmperialString(final Date date, final String pattern) {
		final DateFormat f = new SimpleDateFormat(pattern, IMPERIAL_LOCALE);
		return f.format(date);
	}

	static public String dateToString(final Date date, final String pattern) {
		final DateFormat f = new SimpleDateFormat(pattern);
		return f.format(date);
	}

	/**
	 * <p>
	 * カレンダーを取得する
	 * </p>
	 * 
	 * @param date
	 * @return
	 */
	private static Calendar getCalendar(final Date date) {
		final Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(Calendar.SUNDAY);
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal;
	}

	/**
     * 
     */
	private DateUtils() {
	}
}